package org.example.common

import org.apache.spark.sql.{DataFrame, SparkSession}
import org.example.utils.CommonUtils
import org.slf4j.LoggerFactory

import java.text.SimpleDateFormat
import java.util
import java.util.Calendar

/**
 * 离线基础类
 */
class OfflineBase extends Serializable  {

  protected val LOG = LoggerFactory.getLogger("OfflineBase")

  private val sparkSession = CommonUtils.getSparkSession()


  def doBussiness(): Unit = {
    doTask(sparkSession)
  }

  /**
    * 子类需要重写的业务方法
    *
    * @param sparkSession sparkSession
    */
  protected def doTask(sparkSession: SparkSession): Unit = {

  }
  /**
    * 将数据保存到hive表中
    *
    * @param dataFrame  dataframe
    */
  protected def saveDataToHive(dataFrame: DataFrame, mode: String, tableName: String): Unit = {
    dataFrame
      .write
      .format("hive")
      .mode(mode)
      .insertInto(tableName)
  }

  /**
    * 获取指定日期前几天的年月日
    * @param dateString 时间字符串
    * @param beforeDays 几天前
    * @return
    */
  protected def getBeforeDate(dateString : String, beforeDays : Int, format : String) : String = {
    // 将时间字符串转换为时间类型
    val date = new SimpleDateFormat(getStrFormat(dateString)).parse(dateString)
    // 获取指定时间是一年中的第一天
    val calendar = Calendar.getInstance()
    calendar.setTime(date)
    val dayOfYear = calendar.get(Calendar.DAY_OF_YEAR)

    // 获取指定日期几天前的日期
    calendar.set(Calendar.DAY_OF_YEAR, dayOfYear - beforeDays)
    val preDay = new SimpleDateFormat(format).format(calendar.getTime)
    preDay
  }

  /**
    * 获取指定日期上个月1号的年月日
    * @param dateString 时间字符串
    * @param beforeMonths 几个月前
    * @return
    */
  protected def getLastMonthOne(dateString : String, beforeMonths : Int, format : String) : String = {
    // 将时间字符串转换为时间类型
    val date = new SimpleDateFormat(getStrFormat(dateString)).parse(dateString)
    // 获取指定时间是一年中的第一天
    val calendar = Calendar.getInstance()
    calendar.setTime(date)
    val month = calendar.get(Calendar.MONTH)

    // 获取指定日期几天前的日期
    calendar.set(Calendar.MONTH, month - beforeMonths)
    val preDay = new SimpleDateFormat(format).format(calendar.getTime)
    preDay
  }

  /**
    * 获取输入的时间字符串的格式
    * @param dateString 时间字符串
    * @return 时间字符串对应的格式
    */
  private def getStrFormat(dateString : String) : String = {
    // 要返回的时间格式
    var format = ""
    // 判断时间字符串格式
    if(dateString.contains("-") && dateString.length == 10){
      format = "yyyy-MM-dd"
    } else if (dateString.contains("/") && dateString.length == 10){
      format = "yyyy/MM/dd"
    } else if (dateString.length == 8){
      format = "yyyyMMdd"
    }
    format
  }

  /**
    * 获取指定几周前是哪年第几周
    * @return
    */
  protected def getLastWeek(beforeWeek : Int) : String = {
    // 获取今天日期
    val calendar = Calendar.getInstance()
    // 今天是一年中的第几周
    val week = calendar.get(Calendar.WEEK_OF_YEAR)
    print(week)
    // 获取当前周指定几周前是哪年的第几周
    calendar.set(Calendar.WEEK_OF_YEAR, week - beforeWeek)
    // 返回指定几周前是哪年的第几周
    calendar.get(Calendar.YEAR) + "年第" + calendar.get(Calendar.WEEK_OF_YEAR) + "周"
  }


  /**
    * 获取休息日第一天和最后一天
    * @param dateString 休息日最后一天
    * @param holidayList  休息日列表
    * @return
    */
  protected def getHolidayWorkRange(dateString : String, holidayList : java.util.List[String]) : java.util.ArrayList[String] = {
    // 结果列表
    val resultList = new util.ArrayList[String]()
    // 休息日第一天
    var firstHoliday = dateString
    // 计数器
    var counter = 1
    while(holidayList.contains(getBeforeDate(firstHoliday,1,"yyyy-MM-dd"))){
      firstHoliday = getBeforeDate(firstHoliday,1,"yyyy-MM-dd")
    }
    resultList.add(firstHoliday)
    resultList.add(dateString)
    resultList
  }

  /**
    * 判断字符串中是否包含中文
    * @param str  需要进行判断的字符串
    * @return
    */
  protected def isContainChinese(str : String) : Boolean = {
    var flag = false
    for (i <- 0 until str.length-1) {
      val c = str.charAt(i)
      if(c > 128){
        flag = true
      }
    }
    flag
  }


}
